#include "header/MtFedBk_Processer.h"
#include<iostream>

ProQueue::ProQueue():e_num(0){
    _queue=_rear=nullptr;
}
ProQueue::~ProQueue(){
    PCB *p;
    while(_queue){
        p=_queue->next;
        delete _queue;
        _queue=p;
    }
}
void ProQueue::setTimeLenth(int t){
    time_length=t;
}
PCB* ProQueue::dequeue(){
    PCB*p=_queue;
    _queue=_queue->next;
    e_num--;
    return p;
}
void ProQueue::inqueue(PCB* p){

    if(_rear){
         _rear->next=p;
    }
    else
    {
        _queue=p;
    }
    _rear=p;
    _rear->next=nullptr;
    e_num++;
}

MuFedBk_Processer::MuFedBk_Processer(int n):BaseProcesser(n){
    int mi[8]={1,2,4,8,16,32,64,128};
    const int QUE_NUM=8;
    proqueues=new ProQueue[QUE_NUM];
    for(int i=0;i<QUE_NUM;i++){
        proqueues[i].setTimeLenth(mi[i]);
    }
    type=MtF;
}
void MuFedBk_Processer::first_in(){
    const int QUE_NUM=8;
    int i=0;
    for(;i<QUE_NUM;i++){
        if(!proqueues[i].empty())
        break;
    }
    now_que_level=i;
    running=proqueues[now_que_level].dequeue();
     running->state=State::RUN;
    
}

bool MuFedBk_Processer::do_job(){
    
    int time=running->needtime;
    running->needtime-=proqueues[now_que_level].timeLength();
    running->needtime = running->needtime>0 ? running->needtime:0;
    running->cputime+=time-running->needtime;
    return running->needtime==0;
}


void MuFedBk_Processer::insert_back(){
    if(now_que_level<7)
        proqueues[now_que_level+1].inqueue(running);
    else
        proqueues[now_que_level].inqueue(running);
}

void MuFedBk_Processer::do_creat(int needtime){
    PCB * p_new=empty;
    empty=empty->next;

    p_new->needtime=needtime;
    p_new->name=p_num++;  
    p_new->state=RDY;
    proqueues[0].inqueue(p_new);
}

void MuFedBk_Processer::print_state(){

    for (size_t i = 0; i < 8; i++) {
        PCB *p = proqueues[i].head();
        std::cout << "the readys "<<i<<":\n";
        while (p) {
            std::cout << p->name << '\t' << p->cputime << '\t' << p->prio
                      << '\t' << p->needtime << '\t' << theState(p->state)
                      << std::endl;
            p = p->next;
        }
    }

    std::cout << "the finishs\n";
    PCB *p  = finish;
    while (p) {
        std::cout << p->name << '\t' << p->cputime << '\t' << p->prio << '\t'
                  << p->needtime << '\t' << theState(p->state) << std::endl;
        p = p->next;
	}
}